package com.xw.config;

import com.xw.aspect.Loggable;
import com.xw.dao.UserTokenDao;
import com.xw.entity.OperationLog;
import com.xw.entity.UserToken;
import com.xw.service.OperationLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;
/**
 * @Description:  操作日志切面
 * @Author: ASUS
 * @Date: 2024/12/19 09:15
 * @Version: 1.0
 */
@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private UserTokenDao userTokenDao;

    @Pointcut("@annotation(com.xw.aspect.Loggable)")
    public void loggable() {}

    @Around("loggable()")
    public Object aroundLoggable(ProceedingJoinPoint joinPoint) throws Throwable {
        // 执行目标方法
        Object result = joinPoint.proceed();

        // 创建日志对象
        OperationLog log = new OperationLog();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Loggable annotation = method.getAnnotation(Loggable.class);

        log.setOperation(annotation.value());
        log.setOperationTime(new Date());

        // 获取 HTTP 请求对象
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        if (annotation.requireToken()) {
            // 需要 Token 的情况
            String token = request.getHeader("token");
            if (token == null || token.isEmpty()) {
                throw new IllegalArgumentException("Token is missing or invalid");
            }
            UserToken userToken = userTokenDao.selectByToken(token);
            if (userToken == null) {
                throw new IllegalArgumentException("User token is invalid");
            }
            log.setUserId(Long.valueOf(userToken.getUserId()));
        } else {
            // 不需要 Token 的情况
            log.setUserId(-1L);
        }

        // 获取 IP 地址
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        log.setIpAddress(ipAddress);

        // 保存操作日志
        operationLogService.saveOperationLog(log);

        return result;
    }
}
